//
//  NNImageClipView.swift
//  CommonTool
//
//  Created by Name i on 2022/3/17.
//

import Foundation
import UIKit

 
public class NNImageClipView: UIView {
    
    // 原图展示视图
    private lazy var baseImageView: UIImageView = {
        let img = UIImageView(frame: .zero)
        img.contentMode = .scaleAspectFit
        return img
    }()
    // 裁剪视图
    private lazy var clipView: NNClipDottedLineView = {
        let view = NNClipDottedLineView(frame: .zero)
        view.isUserInteractionEnabled = true
        view.addGestureRecognizer(UIPanGestureRecognizer(target: self,
                                                         action: #selector(panAction(pan:))))
        return view
    }()
    // 原图
    private var image: UIImage = UIImage()
    // 图片裁剪比例，默认正方形
    private var clipScale: CGFloat = 1.0
    // 是否横向展示
    private var isHorizontal: Bool = false
    // 裁剪的区域
    private var clipRect: CGRect = .zero
    // 将用户选择的区域传出去
    private var completeHandle: ((_ selectedRect: CGRect) -> ())?
    
    static func contentSize(contentWidth: CGFloat, image: UIImage?) -> CGSize {
        guard let originImage = image else { return .zero }
        return CGSize(width: contentWidth, height: contentWidth * originImage.size.height / originImage.size.width)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        addSubviews(childs: [baseImageView, clipView])
    }
    
    
    
    public override func layoutSubviews() {
        super.layoutSubviews()
        baseImageView.frame = bounds
        clipView.frame = bounds
    }
    
    
    @objc func panAction(pan: UIPanGestureRecognizer) {
        let translation = pan.translation(in: pan.view)
        if isHorizontal {
            clipRect = CGRect(x: clipRect.origin.x,
                              y: clipRect.origin.y + translation.y,
                              width: clipRect.size.width,
                              height: clipRect.size.height)
        }else {
            clipRect = CGRect(x: clipRect.origin.x + translation.x,
                              y: clipRect.origin.y,
                              width: clipRect.size.width,
                              height: clipRect.size.height)
        }
        // 限制滑动区域
        clipRect.origin.x = max(0, clipRect.origin.x)
        clipRect.origin.x = min(bounds.size.width - clipRect.size.width, clipRect.origin.x)
        clipRect.origin.y = max(0, clipRect.origin.y)
        clipRect.origin.y = min(bounds.size.height - clipRect.size.height, clipRect.origin.y)
        
        clipView.path = reveredPath(toClipRect: clipRect)
        pan.setTranslation(.zero, in: pan.view)
        completeHandle?(clipRect)
    }
    
    // 将裁剪区域反转
    private func reveredPath(toClipRect: CGRect) -> UIBezierPath {
        let path = UIBezierPath(rect: bounds)
        path.append(UIBezierPath(roundedRect: toClipRect,
                                 byRoundingCorners: .allCorners,
                                 cornerRadii: CGSize(width: 2.0, height: 2.0)).reversing())
        return path
    }
}


public extension NNImageClipView  {
    
    func config(image: UIImage,
                       clipScale: CGFloat,
                       completeHandle: @escaping ((_ selectedRect: CGRect) -> ())) {
        
        self.baseImageView.image = image
        self.clipScale = clipScale
        self.completeHandle = completeHandle
        
        if image.size.width == 0 || image.size.height == 0 { return }
        if frame.size.height == 0 { return }
        
        let frameScale = frame.size.width / frame.size.height
        
        isHorizontal = clipScale > frameScale
        if isHorizontal {
            // 横图: 以frame宽度为准
            clipRect = CGRect(x: 0,
                                    y: (frame.size.height - frame.size.height / clipScale * frameScale) * 0.5,
                                    width: frame.size.width,
                                    height: frame.size.height / clipScale * frameScale)
        }else {
            // 竖图：以frame的高为准
            clipRect = CGRect(x: (frame.size.width - frame.size.width / frameScale * clipScale) * 0.5,
                                    y: 0,
                                    width: frame.size.width / frameScale * clipScale,
                                    height: frame.size.height)
        }
        clipView.path = reveredPath(toClipRect: clipRect)
    }

    func clipImage() -> UIImage? {
        guard let image = baseImageView.image else { return nil }
        UIGraphicsBeginImageContextWithOptions(clipRect.size, false, UIScreen.main.scale)
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        context.clip(to: CGRect(origin: .zero, size: clipRect.size))
        image.draw(in: CGRect(origin: CGPoint(x: -clipRect.origin.x, y: -clipRect.origin.y), size: bounds.size))
        let contextImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return contextImage
    }
}



class NNClipDottedLineView: UIView {
    
    private lazy var dottedLine: CAShapeLayer = {
        let dottedLine = CAShapeLayer()
        dottedLine.fillColor = UIColor.red.cgColor
        dottedLine.strokeColor = UIColor.orange.cgColor
        return dottedLine
    }()
    
    var path: UIBezierPath? {
        didSet {
            dottedLine.path = path?.cgPath
            setNeedsDisplay()
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupUI()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    private func setupUI() {
        backgroundColor = .black.withAlphaComponent(0.5)
        layer.mask = dottedLine
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        dottedLine.bounds = bounds
        dottedLine.position = CGPoint(x: bounds.size.width * 0.5, y: bounds.size.height * 0.5)
    }
}
